#include "csv2sql.h"

namespace csv2sql
{
  
  SqlWriter::SqlWriter(Options *o)
  {
    options = o;
    rowNum = colNum = 0;
  }
  SqlWriter::SqlWriter()
  {
    rowNum = colNum = 0;
  }

  bool SqlWriter::WriteFile()
  {
    Scanner s = Scanner(options);
    meta = s.Scan();
    Parser p = Parser(options, this);
    return p.Parse();
  }

  bool SqlWriter::Start()
  {
    fprintf(stdout,"\n");
    printf("CREATE TABLE  `%s` (\n",options->table);
    for (int i = 0; i<meta->ColCount; i++)
    {
      char *type;
      char sizeBuf[10];
      char *size = &sizeBuf[0];
      char *deft;
      if (meta->ColTypes[i] == DT_INTEGER)
      {
        type = (char *)"INT";
        deft = (char *)"0";
        sprintf (sizeBuf, "(11)");
      }
      else if (meta->ColTypes[i] == DT_DECIMAL)
      {
        type = (char *)"DECIMAL";
        deft = (char *)"0";
        sprintf (sizeBuf, "(%i,%i)", 
                meta->ColSizes[i].Left,
                meta->ColSizes[i].Right);
      }
      else if (meta->ColTypes[i] == DT_DATE)
      {
        type = (char *)"DATETIME";
        deft = (char *)"'0000-00-00 00:00:00'";
        sprintf (sizeBuf, "");
      }
      else if (meta->ColSizes[i].Left * 2 < 256)
      {
        type = (char *)"VARCHAR";
        deft = (char *)"''";
        sprintf (sizeBuf, "(%i)", meta->ColSizes[i].Left * 2);
      }
      else
      {
        type = (char *)"TEXT";
        deft = (char *)"''";
        sprintf (sizeBuf, ""); 
      }
      printf("`%s` %s%s NOT NULL default %s %s\n",
              meta->ColNames[i],
              type, size, deft, i==meta->ColCount-1?");":",");
    }
    fprintf(stdout,"\n");
    return true;
  }
  
  bool SqlWriter::Write(int c, ParserMode m)
  {
    const char *escape =  "\"%";
    if ( strchr(escape, c) != NULL )
      return fprintf(stdout,"\\%c",c);
    return fprintf(stdout,"%c",c);
  }

  bool SqlWriter::StartRow(ParserMode m)
  {
    rowNum++;
    if (rowNum>2)
      fprintf(stdout,", \n");
    else if (rowNum>1)
      fprintf(stdout," VALUES \n");
    else
      return fprintf(stdout,"INSERT INTO `%s` (`", options->table);

    if ( meta->ColTypes[colNum] & (DT_STRING | DT_DATE) )
      fprintf(stdout,"(\"");
    else
      fprintf(stdout,"(");

    return true;
  }

  bool SqlWriter::EndRow(ParserMode m)
  {
    if (m & PM_HEAD)
      fprintf(stdout,"`)");
    else if (m & PM_EMPTY)
      fprintf(stdout,"NULL)");
    else if ( meta->ColTypes[colNum] & (DT_STRING | DT_DATE) )
      fprintf(stdout,"\")");
    else
      fprintf(stdout,")");
    colNum = 0;
    return true;
  }

  bool SqlWriter::StartCell(ParserMode m)
  {
    if (m & PM_HEAD)
      fprintf(stdout,", `");
    else if ( meta->ColTypes[colNum] & (DT_STRING | DT_DATE) )
      fprintf(stdout,"\"");
    return true;
  }
  
  bool SqlWriter::EndCell(ParserMode m)
  {
    
    if (m & PM_HEAD)
      fprintf(stdout,"`");
    else if (m & PM_EMPTY)
      fprintf(stdout,"NULL,");
    else if ( meta->ColTypes[colNum] & (DT_STRING | DT_DATE) )
      fprintf(stdout,"\",");
    else
      fprintf(stdout,",");
    colNum++;
    return true;
  }
  
  bool SqlWriter::End()
  {
    fprintf(stdout,";\n\n");
    return true;
  }
    
}

  
/*
CREATE TABLE  `test`.`foo` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `date` datetime default NULL,
  `price` decimal(6,2) NOT NULL default '0.00',
  `desc` text NOT NULL,
  `opts` varchar(255) default NULL,
  `something` varchar(255) NOT NULL,
  `nothing` varchar(255) default 'foo',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1
*/
